library base_router_helper;

import 'dart:convert';

import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart' as fl;

/// A Calculator.
class RouterHelper {}

class BaseRouterInit {
  static Widget errorWidget;
  static List<BaseRouter> routers;

  static configRoutes(fl.FluroRouter router) {
    router.notFoundHandler = fl.Handler(handlerFunc: (ctx, params) {
      return errorWidget ??
          Scaffold(
            body: Center(
              child: Text(
                "布局错误",
                style: TextStyle(fontSize: 18, color: Colors.red),
              ),
            ),
          );
    });
    initRotePaths(router);
  }

  static initRouterInit(List<BaseRouter> routerList, fl.FluroRouter router,
      {Widget error}) {
    errorWidget = error;
    routers = routerList;
    configRoutes(router);
  }

  static initErrorWidget(Widget error) {
    errorWidget = error;
  }

  static initRouterList(List<BaseRouter> routerList) {
    routers = routerList;
  }

  static void initRotePaths(fl.FluroRouter router) {
    routers.forEach((element) {
      element.initRouterPage(router);
    });
  }
}

class NavigationUtil {
  static fl.FluroRouter router;

  static initRouter(fl.FluroRouter initRouter) {
    router = initRouter;
  }

  static push2page<T>(BuildContext c, String path,
      {Map<String, Object> params,
        bool replace = false,
        bool clearStack = false,
        bool maintainState = true,
        bool rootNavigator = false,
        bool nullOk = false,
        TransitionType transition = TransitionType.cupertino,
        Duration transitionDuration,
        RouteTransitionsBuilder transitionBuilder,
        RouteSettings routeSettings,
        ValueChanged<T> resultCallBack}) async {
    StringBuffer sbuf = StringBuffer();
    sbuf.write(path);
    if (params != null) dealMap(params, sbuf);
    T t = await router.navigateTo(c, sbuf.toString(),
        replace: replace,
        clearStack: clearStack,
        maintainState: maintainState,
        rootNavigator: rootNavigator,
        nullOk: nullOk,
        transition: transition,
        transitionDuration: transitionDuration,
        transitionBuilder: transitionBuilder,
        routeSettings: routeSettings);
    resultCallBack?.call(t);
  }

  static void dealMap(Map<String, Object> params, StringBuffer sbuf) {
    if (params.isNotEmpty) {
      sbuf.write("?");
    }
    for (int i = 0; i < params.keys.length; i++) {
      String key = params.keys.elementAt(i);
      var value;
      if (params[key] is String) {
        value = _fluroCnParamsEncode(params[key]);
      } else {
        value = params[key];
      }
      if (i != 0) {
        sbuf.write("&");
      }
      sbuf.write("$key=$value");
    }
  }

  static pop(BuildContext c) {
    router.pop(c);
  }

  static popUntil(BuildContext c, {String pathName}) {
    if (pathName == null) {
      Navigator.popUntil(c, (route) => route.isFirst);
    } else {
      Navigator.of(c).popUntil(ModalRoute.withName(pathName));
    }
  }

  ///字符串编码
  static String _fluroCnParamsEncode(String originalCn) {
    return jsonEncode(Utf8Encoder().convert(originalCn));
  }
}

abstract class BaseRouter {
  initRouterPage(fl.FluroRouter router);

  int getIntExtra(String key, Map<String, List<String>> map) =>
      int.parse(map[key].first);

  double getDoubleExtra(String key, Map<String, List<String>> map) =>
      double.parse(map[key].first);

  bool getBoolExtra(String key, Map<String, List<String>> map) =>
      map[key].first == "true";

  String getStringExtra(String key, Map<String, List<String>> map) =>
      _fluroCnParamsDecode(map[key].first);

  ///字符串解码
  String _fluroCnParamsDecode(String encodeCn) {
    var list = List<int>();

    jsonDecode(encodeCn).forEach(list.add);
    return Utf8Decoder().convert(list);
  }
}
